// 文件上传组件
const FileUpload = {
  template: `
        <div class="upload-section">
            <div class="section-title">
                <div class="info-icon">i</div>
                文件上传
            </div>
            <div class="upload-zone" @click="selectFiles">
                <div class="upload-icon">↑</div>
                <div class="upload-text">选择文件</div>
                <div class="upload-hint">可选择单个文件、多个文件</div>
            </div>
            <div class="upload-actions" v-if="selectedFiles.length > 0 || isUploading">
                <div class="selected-files-info" v-if="selectedFiles.length > 0 && !isUploading">
                    已选择 {{ selectedFiles.length }} 个文件
                </div>
                <div v-if="currentUploadingFile" class="current-file">
                    正在上传: {{ currentUploadingFile }}
                </div>
                <div v-if="uploadProgress > 0" class="upload-progress">
                    <div class="progress-bar">
                        <div class="progress-fill" :style="{ width: uploadProgress + '%' }"></div>
                    </div>
                    <div class="progress-text">{{ uploadProgress }}%</div>
                    <div v-if="uploadingFiles.size > 0" class="chunk-info">
                        分片上传进度: {{ getChunkProgressText() }}
                    </div>
                </div>
            </div>
        </div>
    `,

  data() {
    return {
      selectedFiles: [],
      isUploading: false,
      uploadProgress: 0,
      // 分片上传相关
      // chunkSize: 1 * 1024 * 1024, // 1MB per chunk
      chunkSize: 1 * 1024, // 1KB per chunk
      uploadingFiles: new Map(), // 存储正在上传的文件信息
      currentUploadingFile: null,
      // 已弃用：不再使用 uploadedFiles，完全依赖后端数据
      // uploadedFiles: [], // 存储已上传的文件列表
    };
  },

  methods: {
    /**
     * 获取分片进度文本
     */
    getChunkProgressText() {
      const progressTexts = Array.from(this.uploadingFiles.values()).map(
        (f) => `${f.uploadedChunks}/${f.totalChunks}`
      );
      return progressTexts.join(", ");
    },

    /**
     * 显示上传完成统计信息
     * @param {Object} stats - 统计信息对象
     * @param {number} successCount - 成功数量
     * @param {number} failedCount - 失败数量
     */
    showUploadSummary(stats, successCount, failedCount) {
      // 构建统计信息文本（使用用户友好的表达）
      const summaryParts = [];

      if (stats.new > 0) {
        summaryParts.push(`上传 ${stats.new} 个`);
      }
      if (stats.retry > 0) {
        summaryParts.push(`重新上传 ${stats.retry} 个`);
      }
      if (stats.repair > 0) {
        summaryParts.push(`补传 ${stats.repair} 个`);
      }
      if (stats.overwrite > 0) {
        summaryParts.push(`更新 ${stats.overwrite} 个`);
      }
      if (stats.skip > 0) {
        summaryParts.push(`已存在 ${stats.skip} 个`);
      }
      if (stats.failed > 0) {
        summaryParts.push(`失败 ${stats.failed} 个`);
      }

      // 生成消息文本
      let message = "";
      let messageType = "success";

      if (stats.failed > 0) {
        messageType = "warning";
        message = `上传完成：${summaryParts.join("，")}`;
      } else if (stats.skip > 0 && successCount === 0) {
        // 全部跳过
        messageType = "info";
        message = `所选文件已全部存在，共 ${stats.skip} 个文件`;
      } else if (successCount > 0) {
        message = `上传完成：${summaryParts.join("，")}`;
      } else {
        message = "上传完成";
      }

      // 显示消息
      if (message) {
        if (messageType === "success") {
          ElMessage.success(message);
        } else if (messageType === "warning") {
          ElMessage.warning(message);
        } else {
          ElMessage.info(message);
        }
      }
    },

    /**
     * 格式化文件名列表用于显示（限制长度，避免消息过长）
     * @param {Array<string>} fileNames - 文件名数组
     * @param {number} maxDisplayCount - 最多显示的文件名数量，默认10
     * @returns {Object} { displayMessage: string, shouldLogFullList: boolean }
     */
    formatFileNamesForDisplay(fileNames, maxDisplayCount = 10) {
      if (!fileNames || fileNames.length === 0) {
        return { displayMessage: "", shouldLogFullList: false };
      }

      if (fileNames.length <= maxDisplayCount) {
        // 文件数量不多，全部显示
        return {
          displayMessage: fileNames.join("、"),
          shouldLogFullList: false,
        };
      } else {
        // 文件数量较多，只显示前几个，其余用"... 等N个文件"表示
        const displayNames = fileNames.slice(0, maxDisplayCount).join("、");
        return {
          displayMessage: `${displayNames} ... 等共${fileNames.length}个文件`,
          shouldLogFullList: true,
        };
      }
    },

    /**
     * 计算文件SHA-256哈希值
     */
    calculateFileSHA256(file) {
      return new Promise((resolve, reject) => {
        const fileReader = new FileReader();

        fileReader.onload = async (e) => {
          try {
            const arrayBuffer = e.target.result;
            // 使用浏览器原生crypto API计算SHA-256
            const hashBuffer = await crypto.subtle.digest(
              "SHA-256",
              arrayBuffer
            );
            // 将ArrayBuffer转换为十六进制字符串
            const hashArray = Array.from(new Uint8Array(hashBuffer));
            const hashHex = hashArray
              .map((b) => b.toString(16).padStart(2, "0"))
              .join("");
            resolve(hashHex);
          } catch (error) {
            reject(new Error("SHA-256计算失败: " + error.message));
          }
        };

        fileReader.onerror = () => {
          reject(new Error("文件读取失败"));
        };

        fileReader.readAsArrayBuffer(file);
      });
    },

    /**
     * 查询已存在的文件记录（包括数据库记录和物理文件存在性检查）
     * 优化：使用批量查询接口，一次查询多个文件，提高性能
     */
    async queryExistingFiles(fileNames) {
      try {
        if (!fileNames || fileNames.length === 0) {
          return [];
        }

        // 并行执行批量查询（数据库查询 + 文件存在性检查）
        const [dbResponse, fileResponse] = await Promise.allSettled([
          // 1. 批量查询数据库记录
          axios.post(
            `/into-iotdb/file-record/batch-query-by-filenames`,
            fileNames
          ),
          // 2. 批量检查物理文件是否存在
          axios.post(
            `/into-iotdb/file-record/batch-check-file-exists`,
            fileNames
          ),
        ]);

        // 处理数据库查询结果
        const dbRecordMap = new Map(); // 文件名 -> 记录对象
        if (
          dbResponse.status === "fulfilled" &&
          dbResponse.value.data.success &&
          dbResponse.value.data.records
        ) {
          const records = dbResponse.value.data.records;
          for (const record of records) {
            if (record && record.fileName) {
              dbRecordMap.set(record.fileName, record);
            }
          }
        } else if (dbResponse.status === "rejected") {
          console.warn("批量查询数据库记录失败:", dbResponse.reason);
        }

        // 处理文件存在性检查结果
        const fileExistsMap = new Map(); // 文件名 -> 是否存在
        if (
          fileResponse.status === "fulfilled" &&
          fileResponse.value.data.success &&
          fileResponse.value.data.fileExistsMap
        ) {
          const existsMap = fileResponse.value.data.fileExistsMap;
          for (const [fileName, exists] of Object.entries(existsMap)) {
            fileExistsMap.set(fileName, exists === true);
          }
        } else if (fileResponse.status === "rejected") {
          console.warn("批量检查文件存在性失败:", fileResponse.reason);
          // 检查失败时，假设所有文件都不存在
          for (const fileName of fileNames) {
            fileExistsMap.set(fileName, false);
          }
        }

        // 构建返回记录数组
        const existingRecords = [];
        for (const fileName of fileNames) {
          const dbRecord = dbRecordMap.get(fileName);
          const fileExists = fileExistsMap.get(fileName) || false;

          if (dbRecord) {
            // 数据库有记录，补充文件存在性信息
            dbRecord.fileExists = fileExists;
            existingRecords.push(dbRecord);
          } else if (fileExists) {
            // 数据库无记录但文件存在（数据不一致场景）
            existingRecords.push({
              fileName: fileName,
              uploadStatus: null,
              fileExists: true,
              isInconsistent: true, // 标记为数据不一致
            });
          }
          // 如果数据库无记录且文件不存在，不添加到 existingRecords（视为新文件）
        }

        return existingRecords;
      } catch (error) {
        console.error("查询文件记录失败:", error);
        // 查询失败时返回空数组，允许继续上传
        return [];
      }
    },

    /**
     * 将文件分片
     */
    sliceFile(file) {
      const chunks = [];
      const totalChunks = Math.ceil(file.size / this.chunkSize);

      for (let i = 0; i < totalChunks; i++) {
        const start = i * this.chunkSize;
        const end = Math.min(file.size, start + this.chunkSize);
        const chunk = file.slice(start, end);
        chunks.push({
          chunk: chunk,
          index: i,
          size: chunk.size,
        });
      }

      return chunks;
    },

    selectFiles() {
      const input = document.createElement("input");
      input.type = "file";
      input.multiple = true;
      // input.accept = ".csv"; // 移除CSV格式限制，允许所有文件类型
      // 注意：不设置accept属性，因为与webkitdirectory冲突
      // input.webkitdirectory = true; // 允许选择文件夹

      input.onchange = async (e) => {
        const files = Array.from(e.target.files);
        // 接受所有文件类型，不再过滤
        if (files.length > 0) {
          this.selectedFiles = files;
          this.$emit("files-selected", files);

          // 收集所有文件名，去后端查询同名是否有已经有上传记录
          const fileNames = files.map((file) => file.name);
          const existingRecords = await this.queryExistingFiles(fileNames);

          // 分类处理文件
          const filesToUpload = [];
          const skippedFiles = [];
          const filesToRetry = [];

          for (const file of files) {
            const existingRecord = existingRecords.find(
              (record) => record.fileName === file.name
            );

            if (!existingRecord) {
              // 情况1：数据库无记录且文件不存在 → 新文件，正常上传
              // 设置字段默认值
              file.channelNo = null;
              file.deviceNo = null;
              file.company = "航发黎明";
              file.productPhase = "2";
              file.dataTypeFirst = "4";
              file.dataTypeSecond = null;
              file.dataSource = "台架数采";
              file.startTime = null;
              file.engineId = null;
              file.engineNo = null;
              file.enginePlace = null;
              file.ecuId = null;
              file.ecuNo = null;
              file.ecuSysId = null;
              file.ecuSysNo = null;
              file.subject = null;
              file.remark = null;
              file.checkCode = null;
              file.syncDataSource = 0; // 0-大东
              file.syncStatus = null;
              file.uploadStatus = 1;
              file.retryTime = null;
              filesToUpload.push(file);
            } else if (
              existingRecord.uploadStatus === 1 &&
              existingRecord.fileExists
            ) {
              // 情况2：数据库有记录且文件存在
              if (existingRecord.importStatus === 1) {
                // 如果文件已导入，标记跳过原因（提示在最后统一显示）
                file._skipReason = 'imported'; // 标记跳过原因：已导入
                skippedFiles.push(file);
              } else {
                // 文件已上传但未导入，完全重复，跳过上传
                file._skipReason = 'uploaded'; // 标记跳过原因：已上传
                skippedFiles.push(file);
              }
            } else if (
              existingRecord.uploadStatus === 1 &&
              !existingRecord.fileExists
            ) {
              // 情况3：数据库有记录但文件不存在
              if (existingRecord.importStatus === 1) {
                // 如果文件已导入，标记跳过原因（提示在最后统一显示）
                file._skipReason = 'imported'; // 标记跳过原因：已导入
                skippedFiles.push(file);
              } else {
                // 数据不一致，允许上传修复
                // 设置字段默认值
              file.channelNo = null;
              file.deviceNo = null;
              file.company = "航发黎明";
              file.productPhase = "2";
              file.dataTypeFirst = "4";
              file.dataTypeSecond = null;
              file.dataSource = "台架数采";
              file.startTime = null;
              file.engineId = null;
              file.engineNo = null;
              file.enginePlace = null;
              file.ecuId = null;
              file.ecuNo = null;
              file.ecuSysId = null;
              file.ecuSysNo = null;
              file.subject = null;
              file.remark = null;
              file.checkCode = null;
              file.syncDataSource = 0;
              file.syncStatus = null;
              file.uploadStatus = 1;
              file.retryTime = null;
              filesToUpload.push(file);
              // 添加标记，用于后续提示
              file._isRepairing = true;
              }
            } else if (existingRecord.isInconsistent) {
              // 情况4：文件存在但数据库无记录 → 数据不一致，询问是否覆盖
              const shouldOverwrite = confirm(
                `文件 "${file.name}" 已存在于服务器但数据库无记录（数据不一致）。\n\n` +
                  `是否覆盖现有文件并创建数据库记录？\n\n` +
                  `点击"确定"：覆盖文件并创建记录\n` +
                  `点击"取消"：跳过此文件`
              );
              if (shouldOverwrite) {
                // 设置字段默认值
                file.channelNo = null;
                file.deviceNo = null;
                file.company = "航发黎明";
                file.productPhase = "2";
                file.dataTypeFirst = "4";
                file.dataTypeSecond = null;
                file.dataSource = "台架数采";
                file.startTime = null;
                file.engineNo = null;
                file.enginePlace = null;
                file.subject = null;
                file.remark = null;
                file.checkCode = null;
                file.syncDataSource = 0;
                file.syncStatus = null;
                file.uploadStatus = 1;
                file.retryTime = null;
                filesToUpload.push(file);
                // 添加标记
                file._isOverwriting = true;
              } else {
                file._skipReason = 'user_cancelled'; // 标记跳过原因：用户取消
                skippedFiles.push(file);
              }
            } else if (existingRecord.uploadStatus === 2) {
              // 情况5：文件名相同，并且上传状态为2(上传失败)，则进行上传，后端insert方法改为update方法
              filesToRetry.push({
                file: file,
                recordId: existingRecord.id,
              });
            }
          }

          // 开始上传需要上传的文件
          if (filesToUpload.length > 0 || filesToRetry.length > 0) {
            // 显示跳过文件的提示（如果有的话）
            if (skippedFiles.length > 0) {
              if (files.length === 1 && skippedFiles.length === 1) {
                // 单文件跳过的情况
                ElMessage.info(
                  `文件 "${skippedFiles[0].name}" 已上传成功，将跳过上传`
                );
              } else {
                // 多文件中有跳过的情况
                const skippedNames = skippedFiles.map((f) => f.name);
                const { displayMessage, shouldLogFullList } =
                  this.formatFileNamesForDisplay(skippedNames);
                ElMessage.warning(
                  `以下文件已存在，将跳过上传：${displayMessage}`
                );
                if (shouldLogFullList) {
                  console.log(
                    `跳过的文件完整列表（共${skippedNames.length}个）：`,
                    skippedNames
                  );
                }
              }
            }

            // 数据不一致修复和文件覆盖的情况改为控制台日志，不在界面提示
            const repairingFiles = filesToUpload.filter((f) => f._isRepairing);
            if (repairingFiles.length > 0) {
              const repairingNames = repairingFiles.map((f) => f.name);
              console.log(
                `[数据不一致修复] 数据库记录存在但文件缺失，将重新上传以下文件以修复（共${repairingNames.length}个）：`,
                repairingNames
              );
            }

            const overwritingFiles = filesToUpload.filter(
              (f) => f._isOverwriting
            );
            if (overwritingFiles.length > 0) {
              const overwritingNames = overwritingFiles.map((f) => f.name);
              console.log(
                `[文件覆盖] 将覆盖以下已存在的文件（共${overwritingNames.length}个）：`,
                overwritingNames
              );
            }

            // 传递文件类型信息用于最终统计
            await this.startUpload(
              filesToUpload,
              filesToRetry,
              skippedFiles,
              repairingFiles,
              overwritingFiles
            );
          } else if (skippedFiles.length === files.length) {
            // 所有文件都被跳过 - 根据跳过原因分类提示
            // 分类跳过的原因
            const importedFiles = skippedFiles.filter(f => f._skipReason === 'imported');
            const uploadedFiles = skippedFiles.filter(f => f._skipReason === 'uploaded');
            const cancelledFiles = skippedFiles.filter(f => f._skipReason === 'user_cancelled');
            
            if (files.length === 1) {
              // 单文件情况
              const file = files[0];
              if (file._skipReason === 'imported') {
                ElMessage.warning(
                  `文件 "${file.name}" 已导入，无法重新上传。如需重新导入，请先删除已导入的记录。`
                );
              } else {
                ElMessage.info(
                  `文件 "${file.name}" 已上传成功，无需重复上传`
                );
              }
            } else {
              // 多文件情况 - 分别提示已导入和已上传的文件
              if (importedFiles.length > 0) {
                const importedNames = importedFiles.map((f) => f.name);
                const { displayMessage: importedDisplay, shouldLogFullList: shouldLogImported } =
                  this.formatFileNamesForDisplay(importedNames);
                ElMessage.warning(
                  `以下文件已导入，无法重新上传：${importedDisplay}。如需重新导入，请先删除已导入的记录。`
                );
                if (shouldLogImported) {
                  console.log(
                    `已导入的文件完整列表（共${importedNames.length}个）：`,
                    importedNames
                  );
                }
              }
              
              if (uploadedFiles.length > 0) {
                const uploadedNames = uploadedFiles.map((f) => f.name);
                const { displayMessage: uploadedDisplay, shouldLogFullList: shouldLogUploaded } =
                  this.formatFileNamesForDisplay(uploadedNames);
                ElMessage.info(`以下文件已上传成功：${uploadedDisplay}`);
                if (shouldLogUploaded) {
                  console.log(
                    `已上传成功的文件完整列表（共${uploadedNames.length}个）：`,
                    uploadedNames
                  );
                }
              }
              
              if (cancelledFiles.length > 0) {
                const cancelledNames = cancelledFiles.map((f) => f.name);
                const { displayMessage: cancelledDisplay } =
                  this.formatFileNamesForDisplay(cancelledNames);
                ElMessage.info(`以下文件已跳过：${cancelledDisplay}`);
              }
            }
            // 所有文件都被跳过时，不需要调用startUpload，直接返回
            return;
          }
        } else {
        }
      };

      input.oncancel = () => {};

      input.onerror = (e) => {
        console.error("文件选择出错:", e);
      };

      try {
        input.click();
      } catch (error) {
        console.error("打开文件选择对话框失败:", error);
      }
    },

    /**
     * 上传单个分片
     */
    async uploadChunk(fileId, chunkIndex, chunk, fileSHA256) {
      const formData = new FormData();
      formData.append("fileId", fileId);
      formData.append("chunkIndex", chunkIndex);
      formData.append("chunk", chunk);

      try {
        const response = await axios.post(
          "/into-iotdb/files/upload/chunk",
          formData,
          {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          }
        );

        if (response.data.success) {
          return true;
        } else {
          console.error(`分片 ${chunkIndex} 上传失败:`, response.data.message);
          return false;
        }
      } catch (error) {
        console.error(`分片 ${chunkIndex} 上传出错:`, error);
        return false;
      }
    },

    /**
     * 上传单个文件（分片方式）
     * @param {File} file - 文件对象
     * @param {boolean} isRetry - 是否为重试上传
     * @param {string} recordId - 重试时的记录ID
     */
    async uploadFileWithChunks(file, isRetry = false, recordId = null) {
      try {
        // 计算文件SHA-256哈希值
        const fileSHA256 = await this.calculateFileSHA256(file);

        // 开始上传
        const startFormData = new FormData();
        startFormData.append("fileName", file.name);
        startFormData.append("fileSize", file.size.toString());
        startFormData.append(
          "fileType",
          file.type || "application/octet-stream"
        );

        const startResponse = await axios.post(
          "/into-iotdb/files/upload/start",
          startFormData,
          {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          }
        );

        if (!startResponse.data.success) {
          throw new Error(startResponse.data.message);
        }

        const fileId = startResponse.data.fileId;

        // 分片
        const chunks = this.sliceFile(file);
        const totalChunks = chunks.length;

        // 存储上传信息
        this.uploadingFiles.set(fileId, {
          fileName: file.name,
          totalChunks: totalChunks,
          uploadedChunks: 0,
          fileSHA256: fileSHA256,
        });

        // 逐个上传分片
        for (let i = 0; i < chunks.length; i++) {
          const chunkData = chunks[i];
          const success = await this.uploadChunk(
            fileId,
            chunkData.index,
            chunkData.chunk,
            fileSHA256
          );

          if (!success) {
            throw new Error(`分片 ${chunkData.index} 上传失败`);
          }

          // 更新进度
          const uploadInfo = this.uploadingFiles.get(fileId);
          uploadInfo.uploadedChunks++;
          this.uploadingFiles.set(fileId, uploadInfo);

          // 计算整体进度
          const fileProgress = (uploadInfo.uploadedChunks / totalChunks) * 100;
          this.uploadProgress = Math.round(fileProgress);
        }

        // 完成上传
        const completeFormData = new FormData();
        completeFormData.append("fileId", fileId);
        completeFormData.append("fileSHA256", fileSHA256);

        const completeResponse = await axios.post(
          "/into-iotdb/files/upload/complete",
          completeFormData,
          {
            headers: {
              "Content-Type": "multipart/form-data",
            },
          }
        );

        // 使用后端返回的SHA256值（如果可用），确保前后端一致
        if (completeResponse.data.calculatedSHA256) {
          const uploadInfo = this.uploadingFiles.get(fileId);
          if (uploadInfo) {
            uploadInfo.fileSHA256 = completeResponse.data.calculatedSHA256;
            this.uploadingFiles.set(fileId, uploadInfo);
          }

          // 如果哈希验证失败，记录警告
          if (completeResponse.data.hashValid === false) {
            console.warn(`文件 ${file.name} SHA256验证失败`);
            ElMessage.warning(
              `文件 ${file.name} 完整性验证失败，请检查文件是否损坏`
            );
          }
        }

        // 完成上传之后，将本次上传结果的文件基本信息保存到数据库
        // 无论成功还是失败，都需要保存记录（成功保存成功记录，失败保存失败记录）
        try {
          if (isRetry) {
            await this.updateFileRecordToDatabase(
              recordId,
              file,
              fileId,
              completeResponse.data.success
            );
          } else {
            await this.saveFileRecordToDatabase(
              file,
              fileId,
              completeResponse.data.success
            );
          }
        } catch (error) {
          console.error(`文件 ${file.name} 记录保存失败:`, error);
          // 显示错误消息给用户
          const errorMessage =
            error.response?.data?.message ||
            error.message ||
            "文件记录保存失败";
          ElMessage.error(`文件 ${file.name} 记录保存失败: ${errorMessage}`);
        }

        // 如果上传失败，抛出异常
        if (!completeResponse.data.success) {
          throw new Error(completeResponse.data.message);
        }

        // 不再使用 addUploadedFile，完全依赖后端数据
        // 文件列表将通过 handleUploadSuccess 中的 loadFileList() 从后端加载

        //确保了 uploadingFiles 中只包含正在上传的文件，已完成上传的文件会被及时清理掉
        this.uploadingFiles.delete(fileId);

        return { success: true, fileId: fileId };
      } catch (error) {
        console.error(`文件 ${file.name} 上传失败:`, error);
        return { success: false, error: error.message };
      }
    },

    async startUpload(
      filesToUpload = [],
      filesToRetry = [],
      skippedFiles = [],
      repairingFiles = [],
      overwritingFiles = []
    ) {
      const totalFiles = filesToUpload.length + filesToRetry.length;
      if (totalFiles === 0) {
        return;
      }

      this.isUploading = true;
      this.uploadProgress = 0;

      try {
        const allFiles = [
          ...filesToUpload.map((file) => ({
            file,
            isRetry: false,
            fileType: file._isRepairing
              ? "repair"
              : file._isOverwriting
              ? "overwrite"
              : "new",
          })),
          ...filesToRetry.map((item) => ({
            file: item.file,
            recordId: item.recordId,
            isRetry: true,
            fileType: "retry",
          })),
        ];

        console.log(
          "开始分片上传文件:",
          allFiles.map((item) => item.file.name)
        );

        const uploadResults = [];

        // 逐个上传文件
        for (let i = 0; i < allFiles.length; i++) {
          const item = allFiles[i];
          const { file, recordId, isRetry } = item;
          this.currentUploadingFile = file.name;

          console.log(
            `正在上传文件 ${i + 1}/${totalFiles}: ${file.name}${
              isRetry ? " (重试)" : ""
            }`
          );

          const result = await this.uploadFileWithChunks(
            file,
            isRetry,
            recordId
          );
          uploadResults.push({
            fileName: file.name,
            success: result.success,
            error: result.error,
            isRetry: isRetry,
            fileType: item.fileType, // 记录文件类型：new, repair, overwrite, retry
          });

          if (!result.success) {
            console.error(`文件 ${file.name} 上传失败:`, result.error);
          }
        }

        // 统计上传结果
        const successResults = uploadResults.filter((r) => r.success);
        const failedResults = uploadResults.filter((r) => !r.success);
        const successCount = successResults.length;
        const failedCount = failedResults.length;

        // 按文件类型统计成功数量
        const stats = {
          new: successResults.filter((r) => r.fileType === "new").length,
          repair: successResults.filter((r) => r.fileType === "repair").length,
          overwrite: successResults.filter((r) => r.fileType === "overwrite")
            .length,
          retry: successResults.filter((r) => r.fileType === "retry").length,
          skip: skippedFiles.length,
          failed: failedCount,
        };

        console.log(`上传完成统计:`, stats);
        console.log(
          `上传完成: 成功 ${successCount} 个，失败 ${failedCount} 个`
        );

        // 通知父组件上传结果
        this.$emit("upload-success", {
          success: failedCount === 0,
          totalFiles: totalFiles,
          successCount: successCount,
          failedCount: failedCount,
          results: uploadResults,
          stats: stats,
        });

        // 重置状态
        this.selectedFiles = [];
        this.uploadProgress = 0;
        this.currentUploadingFile = null;
        this.uploadingFiles.clear();

        // 统一显示统计信息
        this.showUploadSummary(stats, successCount, failedCount);
      } catch (error) {
        console.error("上传过程出错:", error);

        // 通知父组件上传失败
        this.$emit("upload-error", error);

        // 显示错误消息
        ElMessage.error(
          "文件上传失败：" + (error.response?.data?.message || error.message)
        );

        // 重置状态
        this.selectedFiles = [];
        this.uploadProgress = 0;
        this.currentUploadingFile = null;
        this.uploadingFiles.clear();
      } finally {
        this.isUploading = false;
      }
    },

    /**
     * 获取已上传的文件列表（已弃用）
     * 现在完全依赖后端数据，不再使用本地 uploadedFiles
     */
    getUploadedFiles() {
      return [];
    },

    /**
     * 添加已上传的文件到列表（已弃用）
     * 现在完全依赖后端数据，文件列表通过父组件的 loadFileList() 从后端加载
     */
    addUploadedFile(file, fileId) {
      // 已弃用：不再添加到本地列表，完全依赖后端数据
      // 保留方法以防其他地方调用，但不执行任何操作
    },

    /**
     * 保存文件记录到数据库
     * @param {File} file - 文件对象
     * @param {string} fileId - 文件ID
     * @param {boolean} success - 上传是否成功
     */
    async saveFileRecordToDatabase(file, fileId, success) {
      //success为true表示上传成功，false表示上传失败。转化为uploadStatus：1-上传成功；2-上传失败
      const uploadStatus = success ? 1 : 2;
      try {
        // 从上传信息中获取SHA256哈希值
        const uploadInfo = this.uploadingFiles.get(fileId);
        const fileSHA256 = uploadInfo ? uploadInfo.fileSHA256 : null;

        // 构建文件记录对象，使用文件对象上设置的默认值
        const fileRecord = {
          fileName: file.name,
          projectNo: file.projectNo || null,
          place: file.place || null,
          company: file.company || null,
          productPhase: file.productPhase || null,
          productPhaseDesc: file.productPhaseDesc || null,
          dataTypeFirst: file.dataTypeFirst || null,
          dataTypeFirstDesc: file.dataTypeFirstDesc || null,
          dataTypeSecond: file.dataTypeSecond || null,
          dataTypeSecondDesc: file.dataTypeSecondDesc || null,
          dataSource: file.dataSource || null,
          engineId: file.engineId || null,
          engineNo: file.engineNo || null,
          channelNo: file.channelNo || null,
          deviceNo: file.deviceNo || null,
          enginePlace: file.enginePlace || null,
          ecuId: file.ecuId || null,
          ecuNo: file.ecuNo || null,
          ecuSysId: file.ecuSysId || null,
          ecuSysNo: file.ecuSysNo || null,
          subject: file.subject || null,
          remark: file.remark || null,
          checkCode: fileSHA256 || file.checkCode || null,
          syncDataSource: file.syncDataSource || 0, // 0-大东
          syncStatus: null, // 上传时不设置同步状态
          uploadStatus: uploadStatus, // 上传成功或失败
          uploadTime: getLocalDateTimeString(), // 设置上传时间为当前本地时间，格式：yyyy-MM-dd HH:mm:ss
          createTime: getLocalDateTimeString(), // 设置创建时间为当前本地时间
          updateTime: getLocalDateTimeString(), // 设置更新时间为当前本地时间
          retryTime: file.retryTime || 0,
        };

        // 调用后端接口保存文件记录
        const response = await axios.post(
          "/into-iotdb/file-record/insert",
          fileRecord,
          {
            headers: {
              "Content-Type": "application/json",
            },
          }
        );

        if (!response.data.success) {
          throw new Error(response.data.message || "保存文件记录失败");
        }

        return response.data;
      } catch (error) {
        console.error("保存文件记录时发生错误:", error);
        throw error;
      }
    },

    /**
     * 更新文件记录到数据库（用于重试上传）
     * @param {string} recordId - 记录ID
     * @param {File} file - 文件对象
     * @param {string} fileId - 文件ID
     * @param {boolean} success - 上传是否成功
     */
    async updateFileRecordToDatabase(recordId, file, fileId, success) {
      //success为true表示上传成功，false表示上传失败。转化为uploadStatus：1-上传成功；2-上传失败
      const uploadStatus = success ? 1 : 2;
      try {
        // 从上传信息中获取SHA256哈希值
        const uploadInfo = this.uploadingFiles.get(fileId);
        const fileSHA256 = uploadInfo ? uploadInfo.fileSHA256 : null;

        // 构建文件记录对象，用于更新，使用文件对象上设置的默认值
        const fileRecord = {
          id: recordId, // 重要：包含ID用于更新
          fileName: file.name,
          uploadStatus: uploadStatus, // 上传成功或失败
          // 更新方法：只设置 updateTime，createTime 和 uploadTime 保留不更新（由后端处理）
          updateTime: getLocalDateTimeString(), // 更新修改时间，格式：yyyy-MM-dd HH:mm:ss
          checkCode: fileSHA256 || file.checkCode || null,
          // 使用文件对象上的默认值
          projectNo: file.projectNo || null,
          place: file.place || null,
          company: file.company || null,
          productPhase: file.productPhase || null,
          productPhaseDesc: file.productPhaseDesc || null,
          dataTypeFirst: file.dataTypeFirst || null,
          dataTypeFirstDesc: file.dataTypeFirstDesc || null,
          dataTypeSecond: file.dataTypeSecond || null,
          dataTypeSecondDesc: file.dataTypeSecondDesc || null,
          dataSource: file.dataSource || null,
          engineId: file.engineId || null,
          engineNo: file.engineNo || null,
          channelNo: file.channelNo || null,
          deviceNo: file.deviceNo || null,
          enginePlace: file.enginePlace || null,
          ecuId: file.ecuId || null,
          ecuNo: file.ecuNo || null,
          ecuSysId: file.ecuSysId || null,
          ecuSysNo: file.ecuSysNo || null,
          subject: file.subject || null,
          remark: file.remark || null,
          checkCode: file.checkCode || null,
          syncDataSource: file.syncDataSource || 0, // 0-大东
          syncStatus: null, // 上传时不设置同步状态
          retryTime: file.retryTime || 0,
        };

        // 调用后端更新接口
        const response = await axios.put(
          "/into-iotdb/file-record/update",
          fileRecord,
          {
            headers: {
              "Content-Type": "application/json",
            },
          }
        );

        if (!response.data.success) {
          throw new Error(response.data.message || "更新文件记录失败");
        }

        return response.data;
      } catch (error) {
        console.error("更新文件记录时发生错误:", error);
        throw error;
      }
    },
  },
};

/**
 * 获取本地时间字符串，格式：yyyy-MM-dd HH:mm:ss
 * @returns {string} 格式化的本地时间字符串
 */
function getLocalDateTimeString() {
  const now = new Date();
  const year = now.getFullYear();
  const month = String(now.getMonth() + 1).padStart(2, "0");
  const day = String(now.getDate()).padStart(2, "0");
  const hours = String(now.getHours()).padStart(2, "0");
  const minutes = String(now.getMinutes()).padStart(2, "0");
  const seconds = String(now.getSeconds()).padStart(2, "0");
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
